package apiexample.transform;

import java.io.PrintStream;
import java.sql.Connection;
import java.util.ArrayList;

import apiexample.transform.datastructure.UsageExample;

import dao.QueryPageDao;
import dao.entity.PageEntity;
import dao.entity.QueryEntity;
import dao.entity.QueryPageRelation;

public class TransformThread implements Runnable {
	
	private int thread_id;
	private static int query_count = 0;
	
	private Connection apiexample_conn = null;
	
	private Connection apiserver_conn = null;
	
	private TransformLogic logic = null;
	
	private PrintStream os = null;
	
	private PrintStream errs  = null;
	
	public TransformThread(int id, Connection apiexample_conn, Connection apiserver_conn, PrintStream os, PrintStream errs){
		this.thread_id = id;
		this.apiexample_conn = apiexample_conn;
		this.apiserver_conn = apiserver_conn;
		
		if(this.apiexample_conn == null || this.apiserver_conn == null){
			System.err.println("["+thread_id+"] Connection is null!!");
			System.exit(1);
		}
		if(os!=null){
			System.setOut(os);
		}
		if(errs != null){
			System.setErr(errs);
		}	
		
		logic = new TransformLogic(apiexample_conn, apiserver_conn);
		
		System.err.println("["+thread_id+"] Created!!");
	}
	public void run() {
		System.err.println("["+thread_id+"] Start job!!");
		ArrayList<String> processedQueries = new ArrayList<String>();
		QueryEntity query = null;
		while ((query = CentralDataPool.getNextQuery()) != null) {
			processedQueries.add(query.getContent());
			doTransform(query);
		}
		System.err.println("["+thread_id+"] Finished job!!Closing printstream");
		System.err.println("["+thread_id+"]Precessed "+processedQueries.size()+" queries:");
		for (String queryname : processedQueries) {
			System.err.println(queryname);
		}
		try{
			if(os!=null){
				os.close();
			}
			if(errs!=null){
				errs.close();
			}
		}catch(Exception e){
			e.printStackTrace();
		}		
	}
	
	
	public void doTransform(QueryEntity query) {
		// Get id of the api in the apiserver database
		String apiName = CentralDataPool.apiIdMapName.get(query.getApi_id());
		System.err.println("[INFO]["+thread_id+"]Processing " + (++query_count)
				+ "th API:" + apiName);
		int classID;
		if (apiName == null) {
			return;
		} else {
			Integer classIDIneger = CentralDataPool.classNameMapID.get(apiName);
			if (classIDIneger == null) {
				return;
			} else {
				classID = classIDIneger.intValue();
			}
		}
		// Got the API's id in the apiserver database

		long time_3 = System.currentTimeMillis();
		ArrayList<QueryPageRelation> queryPageRelations = QueryPageDao
				.getPageListByQueryID(apiexample_conn, query.getId());
		System.out.println("[INFO]["+thread_id+"]Having:" + queryPageRelations.size()
				+ " related pages");

		long time_4 = System.currentTimeMillis();
		System.out.println("[INFO]["+thread_id+"]Get pages of an API finished, time cost:" + (time_4 - time_3));
		// for each page, get its segments, then identify code snippets and
		// their surrounding texts

		for (QueryPageRelation queryPageRelation : queryPageRelations) {
			try{				
				String pageLink = CentralDataPool.idMapLink.get(queryPageRelation.getPage_id());
				if (pageLink == null) {
					continue;
				} else {
					PageEntity page = CentralDataPool.linkMapPage.get(pageLink);
					if (page == null) {
						continue;
					} else {
						// go on
						// get this page's examples
						System.out.println(page.getLink());
						long time_5 = System.currentTimeMillis();
						// Get all available UsageExamples in this page
						ArrayList<UsageExample> usageExamples = logic.getExamplesInOnePage(
								page.getId(), page.getLink(), classID, page
										.getTitle());
						System.out.println("[INFO]["+thread_id+"]There are "
								+ usageExamples.size()
								+ " usageexamples in page:" + page.getId()
								+ " " + page.getLink());
						long time_6 = System.currentTimeMillis();
						System.out
								.println("[INFO]["+thread_id+"]Get examples in one page finished, time cost:"
										+ (time_6 - time_5));
						// update example's structure information and descriptive texts
						ArrayList<UsageExample> validExamples = logic.updateUsageExample(usageExamples);
						long time_7 = System.currentTimeMillis();
						System.out
								.println("[INFO]["+thread_id+"]Update examples finished, time cost:"
										+ (time_7 - time_6));
						// store back into apiserver
						logic.storeBack(validExamples);

						long time_8 = System.currentTimeMillis();
						System.out
								.println("[INFO]["+thread_id+"]Store back finished, time cost:"
										+ (time_8 - time_7));
					}
				}			
			}catch(Exception e){
				e.printStackTrace();
			}
		}
		// parse code
		System.out.println("[INFO]["+thread_id+"]Finished one API, time cost:" + (System.currentTimeMillis() - time_3));
	
	}

}
